home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / mg / gl / mgglmesh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-06  |  7.1 KB  |  335 lines

  1. /* Copyright (c) 1992 The Geometry Center; University of Minnesota
  2.    1300 South Second Street;  Minneapolis, MN  55454, USA;
  3.    
  4. This file is part of geomview/OOGL. geomview/OOGL is free software;
  5. you can redistribute it and/or modify it only under the terms given in
  6. the file COPYING, which you should have received along with this file.
  7. This and other related software may be obtained via anonymous ftp from
  8. geom.umn.edu; email: software@geom.umn.edu. */
  9.  
  10. /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
  11.  
  12. #include <gl/gl.h>
  13. #include <mgP.h>
  14. #include <mgglP.h>
  15.  
  16. #undef P
  17. /* ^^^ evil kludge XXX to get the P variables here to not get confused
  18.  * with the P prototype macro. -nils */
  19. #define    HAS_N    1
  20. #define    HAS_C    2
  21. #define    HAS_SMOOTH 4
  22.  
  23. int
  24. mggl_mesh( wrap, nu, nv, P, N, C)
  25.     int wrap;
  26.     int nu, nv;
  27.     HPoint3 *P;
  28.     Point3 *N;
  29.     ColorA *C;
  30. {
  31.   return mgsubmesh( wrap, nu, nv, 0, nu-1, 0, nv-1, P, N, C);
  32. }
  33.  
  34. mgsubmesh( wrap, nu, nv, umin, umax, vmin, vmax, meshP, meshN, meshC)
  35.     int wrap;
  36.     int umin, umax, vmin, vmax;
  37.     HPoint3 *meshP;
  38.     Point3 *meshN;
  39.     ColorA *meshC;
  40. {
  41.   register int u, v;
  42.   int ucnt, vcnt;
  43.   register HPoint3 *P;
  44.   register Point3 *N;
  45.   register ColorA *C;
  46.   register int prev;
  47.   int du;
  48.   int douwrap;
  49.   HPoint3  tp;
  50.   Point3 tn;
  51.   int i;
  52.   int has;
  53.   Appearance *ap;
  54.  
  55.  
  56.   if(nu <= 0 || nv <= 0)
  57.     return 0;
  58.  
  59.   ap = &_mgc->astk->ap;
  60.   if ((_mgc->astk->mat.override & MTF_DIFFUSE) && !_mgc->astk->useshader)
  61.     meshC = 0;
  62.  
  63.   has = 0;
  64.   if(meshN)
  65.     has = HAS_N;
  66.   if(meshC)
  67.     has |= HAS_C;
  68.   if(ap->shading == APF_SMOOTH)
  69.     has |= HAS_SMOOTH;
  70.  
  71.  
  72.   if( ap->flag & APF_FACEDRAW ) {    /* Draw faces */
  73.  
  74.     /* We triangulate strips of (v,u) mesh points:
  75.      *  (v,u)    (v,u+1)    (v,u+2) ...
  76.      *  (v+1,u)  (v+1,u+1)  (v+1,u+2) ...
  77.      * using the vertex sequence
  78.      *  (v,u) , (v+1,u), (v,u+1), (v+1,u+1), (v,u+2), ...
  79.      * This covers the territory from v to v+1; then repeat for other v's.
  80.      * If we hit the 256-vertex triangle-mesh limit, the strip is spliced
  81.      * by redrawing the latest (v,u+i),(v+1,u+i) pair of vertices.
  82.      */
  83.  
  84.     register void (*n3func)() = _mgglc->n3f;
  85.     register void (*d4func)() = _mgglc->d4f;
  86.  
  87.     lmcolor(_mgglc->lmcolor);
  88.     if(!(has & HAS_C))
  89.     (*_mgglc->d4f)(&ap->mat->diffuse);
  90.  
  91.     v = vmax - vmin + 1;
  92.     du = umin + vmin * nu;
  93.  
  94.     if(wrap & MM_VWRAP) {
  95.       /* V-wrapping: cur = mesh[vmin,u], prev = mesh[vmax,u] */
  96.       prev = nu * (v - 1);
  97.     } else {
  98.       /* Not V-wrapping: cur = mesh[vmin+1,u], prev = mesh[vmin,u] */
  99.       du += nu;
  100.       prev = -nu;
  101.       v--;    /* One less V-row, too */
  102.     }
  103.  
  104.     do {                    /* Loop over V */
  105.      P = meshP + du;
  106.      N = meshN + du;
  107.      C = meshC + du;
  108.      ucnt = umax - umin + 1;
  109.      if(_mgglc->turbo) {
  110.     mgglpolymeshrow(wrap, has, prev, ucnt, P,
  111.         has&HAS_N ? N : NULL,
  112.         has&HAS_C ? C : NULL);
  113.      } else {
  114.       bgntmesh();
  115.       douwrap = (wrap & MM_UWRAP);
  116.       do {
  117.     /* Loop over U */
  118.     u = ucnt < 126 ? ucnt : 126;    /* 256-vertex tmesh limit */
  119.     ucnt -= u;
  120.  
  121.     switch( has ) {
  122.  
  123.     case 0:
  124.     case HAS_SMOOTH:
  125.       do {
  126.         v4f((float *)P+prev);
  127.         v4f((float *)P);
  128.         P++;
  129.       } while(--u);
  130.       break;
  131.  
  132.     case HAS_C:
  133.       do {
  134.         (*d4func)(C+prev); v4f((float *)(P+prev));
  135.         v4f((float *)P);
  136.         C++; P++;
  137.       } while(--u);
  138.       break;
  139.  
  140.     case HAS_C|HAS_SMOOTH:
  141.       do {
  142.         (*d4func)(C+prev); v4f((float *)(P+prev));
  143.         (*d4func)(C); v4f((float *)P);
  144.         C++; P++;
  145.       } while(--u);
  146.       break;
  147.  
  148.     case HAS_N:
  149.       do {
  150.         (*n3func)(N+prev,P); v4f((float *)(P+prev));
  151.         v4f((float *)P);
  152.         N++; P++;
  153.       } while(--u);
  154.       break;
  155.  
  156.     case HAS_N|HAS_SMOOTH:
  157.       do {
  158.         (*n3func)(N+prev,P); v4f((float *)(P+prev));
  159.         (*n3func)(N,P); v4f((float *)P);
  160.         N++; P++;
  161.       } while(--u);
  162.       break;
  163.  
  164.     case HAS_C|HAS_N:
  165.       do {
  166.         (*d4func)(C+prev); (*n3func)(N+prev,P); v4f((float *)(P+prev));
  167.         v4f((float *)P);
  168.         C++; N++; P++;
  169.       } while(--u);
  170.       break;
  171.  
  172.     case HAS_C|HAS_N|HAS_SMOOTH:
  173.       do {
  174.         (*d4func)(C+prev);    (*n3func)(N+prev,P); v4f((float *)(P+prev));
  175.         (*d4func)(C);    (*n3func)(N,P);    v4f((float *)P);
  176.         C++; N++; P++;
  177.       } while(--u);
  178.       break;
  179.     }
  180.  
  181.     if(ucnt == 0) {
  182.       if(douwrap) {
  183.         douwrap = 0;    /* Loop again on first vertex */
  184.         ucnt = 1;
  185.         P = meshP + du;
  186.         N = meshN + du;
  187.         C = meshC + du;
  188.       }
  189.     } else {
  190.       endtmesh();        /* Hit tmesh limit, splice */
  191.       bgntmesh();
  192.       C--; N--; P--;    /* Redraw last vertex */
  193.     }
  194.       } while(ucnt);
  195.  
  196.       endtmesh();
  197.      }
  198.      prev = -nu;
  199.      du += nu;
  200.    } while(--v > 0);
  201.   }
  202.  
  203.   if(ap->flag & (APF_EDGEDRAW|APF_NORMALDRAW)) {
  204.     lmcolor(LMC_COLOR);
  205.     if(_mgglc->znudge) mggl_closer();
  206.     if(ap->flag & APF_EDGEDRAW) {            /* Draw edges */
  207.     c3f((float *)&ap->mat->edgecolor);
  208.  
  209.     du = umin + vmin * nu;
  210.     ucnt = umax - umin + 1;
  211.     vcnt = vmax - vmin + 1;
  212.     v = vcnt;
  213.     do {
  214.         if(wrap & MM_UWRAP)
  215.         bgnclosedline();
  216.         else
  217.         bgnline();
  218.         u = ucnt;
  219.         P = meshP + du;
  220.         do {
  221.         v4f((float *)P);
  222.         P++;
  223.         } while(--u > 0);
  224.         if(wrap & MM_UWRAP)
  225.         endclosedline();
  226.         else
  227.         endline();
  228.         du += nu;
  229.     } while(--v > 0);
  230.  
  231.     du = umin + vmin * nu;
  232.     u = ucnt;
  233.     do {
  234.         v = vcnt;
  235.         if(wrap & MM_VWRAP)
  236.         bgnclosedline();
  237.         else
  238.         bgnline();
  239.         P = meshP + du;
  240.         do {
  241.         v4f((float *)P);
  242.         P += nu;
  243.         } while(--v > 0);
  244.         if(wrap & MM_VWRAP)
  245.         endclosedline();
  246.         else
  247.         endline();
  248.         du++;
  249.     } while(--u > 0);
  250.     }
  251.  
  252.     if(ap->flag & APF_NORMALDRAW && meshN != NULL) {
  253.     c3f((float *)&ap->mat->normalcolor);
  254.  
  255.     for (i = nu*nv, P=meshP, N=meshN; --i >= 0; P++, N++) {
  256.         mggl_drawnormal(P, N);
  257.     }
  258.     }
  259.     if(_mgglc->znudge) mggl_farther();
  260.   }
  261.   return 1;
  262. }
  263.  
  264. /*
  265.  * Draw a single row of a mesh, using polygons.
  266.  * This routine is needed to work around a bug in Turbo PI graphics:
  267.  * lighted tmesh primitives are not shaded properly.
  268.  * Polygons are OK though, so on Turbo machines we use them.
  269.  */
  270. mgglpolymeshrow(wrap, has, off, count, P, N, C)
  271.     int wrap;
  272.     int has;
  273.     register int off;
  274.     register HPoint3 *P;
  275.     register Point3 *N;
  276.     register ColorA *C;
  277. {
  278.     int k;
  279.     void (*n3func)() = _mgglc->n3f;
  280.     void (*d4func)() = _mgglc->d4f;
  281.  
  282.     if(wrap & MM_UWRAP) {
  283.     k = count-1;
  284.     bgnpolygon();
  285.     if(C) (*d4func)(C+off+k);
  286.     if(N) (*n3func)(N+off+k,P);
  287.     v4f((float *)(P+off+k));
  288.     if(has&HAS_SMOOTH) {
  289.         if(C) (*d4func)(C+k);
  290.         if(N) (*n3func)(N+k,P);
  291.     }
  292.     v4f((float *)(P+k));
  293.     if(has&HAS_SMOOTH) {
  294.         if(C) (*d4func)(C);
  295.         if(N) (*n3func)(N,P);
  296.     }
  297.     v4f((float *)P);
  298.     if(has&HAS_SMOOTH) {
  299.         if(C) (*d4func)(C+off);
  300.         if(N) (*n3func)(N+off,P);
  301.     }
  302.     v4f((float *)(P+off));
  303.     endpolygon();
  304.     }
  305.     k = count;
  306.     do {
  307.     bgnpolygon();
  308.     if(C) (*d4func)(C+off);
  309.     if(N) (*n3func)(N+off,P);
  310.     v4f((float *)(P+off));
  311.     if(has&HAS_SMOOTH) {
  312.         if(C) (*d4func)(C+off);
  313.         if(N) (*n3func)(N+off,P);
  314.         v4f((float *)(P+off));
  315.         if(C) (*d4func)(C++);
  316.         if(N) (*n3func)(N++,P);
  317.         v4f((float *)P++);
  318.         if(C) (*d4func)(C);
  319.         if(N) (*n3func)(N,P);
  320.         v4f((float *)P);
  321.         if(C) (*d4func)(C+off);
  322.         if(N) (*n3func)(N+off,P);
  323.         v4f((float *)(P+off));
  324.     } else {
  325.         v4f((float *)(P+off));
  326.         if(C) C++;
  327.         if(N) N++;
  328.         v4f((float *)(P++));
  329.         v4f((float *)P);
  330.         v4f((float *)(P+off));
  331.     }
  332.     endpolygon();
  333.     } while(--k > 1);
  334. }
  335.